package com.ant.storage.service.impl;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.*;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.*;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DingDingUtil;
import com.ant.storage.utils.RandomUtil;
import com.ant.storage.vo.CommodityVo;
import com.ant.storage.vo.PurchaseDetailsVo;
import com.ant.storage.vo.PurchaseVo;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taobao.api.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author melon
 * @since 2022-03-16
 */
@Service
public class SubscribeServiceImpl extends ServiceImpl<SubscribeMapper, Subscribe> implements ISubscribeService {

    @Resource
    private AuditListMapper auditListMapper;

    @Resource
    private IHistoricalProcurementService historicalProcurementService;

    @Resource
    private PurchaseOrdersMapper purchaseOrdersMapper;

    @Resource
    private IPurchaseOrdersService purchaseOrdersService;

    @Resource
    private IGoodsPoolCommodityService goodsPoolCommodityService;

    @Resource
    private ISubscribeService subscribeService;

    @Resource
    private ISupplierPayListService supplierPayListService;

    @Autowired
    private IPurchaserRecordImgService recordImgService;

    @Resource
    private IAuditListService auditListService;

    @Autowired
    private IPurchaserRecordService purchaserRecordService;

    @Resource
    private PurchaserRecordMapper purchaserRecordMapper;

    @Autowired
    private IPurchaserSubscribeService purchaserSubscribeService;

    @Resource
    private IMergeProcurementService mergeProcurementService;

    @Resource
    private IMergeSubscribeService mergeSubscribeService;

    @Resource
    private MergeProcurementMapper procurementMapper;

    @Resource
    IGoodsPoolService goodsPoolService;

    @Autowired
    IDepartmentService departmentService;

    @Resource
    private CommodityMapper commodityMapper;

    @Autowired
    public ServletContext servletContext;



    @Override
    public PageInfo<Subscribe> queryAllPage(SubscribeDto dto) throws NullPointerException {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        try {
            PageHelper.startPage(dto.getPageIndex(), dto.getPageSize());
            QueryWrapper<Subscribe> wrapper = new QueryWrapper<>();
            // 编号
            if (StringUtils.isNotEmpty(dto.getSubscribeNumber())) {
                wrapper.lambda().like(Subscribe::getSubscribeNumber, dto.getSubscribeNumber().trim());
            }
            //支付方式方式
            if (StringUtils.isNotEmpty(dto.getPayType())) {
                wrapper.lambda().eq(Subscribe::getPayType, dto.getPayType());
            }
            //部门id
            if (dto.getDepartmentId() != null) {
                wrapper.lambda().eq(Subscribe::getDepartmentId, dto.getDepartmentId());
            }
            //采购人id
            if (StringUtils.isNotEmpty(dto.getPurchaserId())) {
                wrapper.lambda().like(Subscribe::getPurchaserId, dto.getPurchaserId());
            }
            // 采购状态
            if (StringUtils.isNotEmpty(dto.getStatus())) {
                wrapper.in("status", Arrays.asList(dto.getStatus().split(",")));
            }
            if (StringUtils.isNotEmpty(dto.getStates())) {
                wrapper.eq("status", dto.getStates());
            }
            if (StringUtils.isNotEmpty(dto.getProcessState())) {
                wrapper.eq("process_state", dto.getProcessState());
            }
            // 采购状态
            if (StringUtils.isNotEmpty(dto.getPurchaseType())) {
                wrapper.lambda().eq(Subscribe::getPurchaseType, dto.getPurchaseType());
            }
            // 是否结算
            if (dto.getReimbursement() != null) {
                wrapper.lambda().eq(Subscribe::getReimbursement, dto.getReimbursement());
            }
            // 是否结算
            if (dto.getTimes() != null && dto.getTimes().size() != 0) {
                wrapper.ge("creation_time", dto.getTimes().get(0) + " 00:00:00");
                wrapper.le("creation_time", dto.getTimes().get(1) + " 23:59:59");
            }

            //procure
            if (userInfo.getRoles() == null) {
                wrapper.lambda().in(Subscribe::getPurchaserId, userInfo.getNameId());
            }else if (userInfo.getRoles() != null && userInfo.getRoles().equals("admin")) {
                wrapper.lambda().in(Subscribe::getCityId, userInfo.getCityId());
            } else if (userInfo.getRoles() != null && userInfo.getRoles().equals("price")) {
                wrapper.lambda().in(Subscribe::getProposerId, userInfo.getNameId())
                        .or().in(Subscribe::getPurchaserId, userInfo.getNameId());
            }else  if (userInfo.getRoles() != null && userInfo.getRoles().equals("warehouse")) {
                wrapper.lambda().in(Subscribe::getProposerId, userInfo.getNameId())
                        .or().in(Subscribe::getPurchaserId, userInfo.getNameId());
            }
            else{
                if (dto.getCityId() != null && dto.getCityId().size() > 0) {
                    wrapper.lambda().in(Subscribe::getCityId, Arrays.asList(dto.getCityId()));
                }
            }
            wrapper.orderByDesc("id", "creation_time");
            List<Subscribe> subscribeList = this.baseMapper.selectList(wrapper);
            subscribeList.forEach(item -> {
                item.setDepartment(departmentService.getDepName(item.getDepartmentId()));
                List<CommodityVo> commodityVo = commodityMapper.commodityAndGoodList(item.getParentId(),
                        dto.getGoodsType());
                item.setCommodityVoList(commodityVo);
                MergeProcurement one = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                        .like("subscribe_id", item.getId()).eq("purchaser_id", item.getPurchaserId()));
                if (one != null) {
                    item.setMergeId(1);
                    item.setMergeIds(one.getSubscribeId().toString());
                } else {
                    item.setMergeIds(item.getId().toString());
                }
                if (dto.getPurchaserId() != null && StringUtils.isNotEmpty(dto.getPurchaserId())) {
                    MergeSubscribe list = mergeSubscribeService.getOne(new QueryWrapper<MergeSubscribe>()
                            .like("subscribe_id", item.getId()).eq("purchaser_id", dto.getPurchaserId()));
                    if (list != null) {
                        item.setStatus(list.getStatus() == 1 ? "3" : item.getStatus());
                        item.setPayStatus(list.getStatus() == 1 ? 2 : item.getPayStatus());
                    }
                    item.setMergeSubscribeList(mergeSubscribeService.list(new QueryWrapper<MergeSubscribe>()
                            .like("subscribe_id", item.getId()).eq("purchaser_id", dto.getPurchaserId())));
                } else {
                    item.setMergeSubscribeList(mergeSubscribeService.list(new QueryWrapper<MergeSubscribe>()
                            .like("subscribe_id", item.getId())));
                }
            });
            subscribeList.sort(Comparator.comparing(Subscribe::getMergeIds).thenComparing(Subscribe::getCreationTime).reversed());
            if (dto.getGoodsType() != null && StringUtils.isNotEmpty(dto.getGoodsType())) {
                subscribeList =
                        subscribeList.stream().filter(v -> v.getCommodityVoList().size() > 0).collect(Collectors.toList());
            }
            PageInfo<Subscribe> pageInfo = new PageInfo<>(subscribeList);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }
    /**
     * 通过id获取采购单详情
     *
     * @param id
     * @return
     */
    @Override
    public Subscribe getPurchaseOrderById(Integer id) {
        if (id == null && id == 0) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else {
            Subscribe subscribe = this.baseMapper.getPurchaseOrderById(id);
            if (subscribe != null) {
                subscribe.getPurchaseVoList().stream().map(item -> {
                    BigDecimal ss = new BigDecimal(item.getCommodityNumber() == null ? "0" : item.getCommodityNumber());
                    item.setTotalPrice(ss.multiply(item.getCommodityPrice() == null ? BigDecimal.valueOf(0) :
                            item.getCommodityPrice()).setScale(2, BigDecimal.ROUND_HALF_UP));
                    List<SupplierListDto> dtoList = new ArrayList<>();
                    supplierPayListService.list(new QueryWrapper<SupplierPayList>()
                            .eq("purchase_orders_id", item.getId())
                            .eq("subscribe_id", id)).stream().map(item1 -> {
                        SupplierListDto dto = new SupplierListDto();
                        dto.setSupplierId(item1.getSupplierId());
                        dto.setAmount(item1.getAmount());
                        item.setSupplierId(item1.getSupplierId());
                        dtoList.add(dto);
                        return null;
                    }).collect(Collectors.toList());
                    item.setSupList(dtoList);
                    return item;
                }).collect(Collectors.toList());
                List<AuditList> auditList = auditListMapper.selectList(new QueryWrapper<AuditList>()
                        .eq("parent_id", id).eq("process_type", "goodsPool"));
                if (auditList.size() > 0) {
                    subscribe.setAuditList(auditList);
                }
                if (subscribe.getBills() != null) {
                    List<PurchaserRecordImg> list = recordImgService.list(new QueryWrapper<PurchaserRecordImg>().in(
                            "id",
                            (subscribe.getBills().split(","))));
                    subscribe.setPurchaserRecordImgList(list);
                }
                return subscribe;
            }
            return null;
        }
    }

    /**
     * 添加计划采购
     *
     * @param subscribeDto
     * @param bindingResult
     * @return
     */
    @Override
    @Transactional
    public ResultVo addPlanPurchase(SubscribeDto subscribeDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new AntException(bindingResult.getFieldError().getDefaultMessage());
        } else {
            Subscribe subscribe = new Subscribe();
            BeanUtils.copyProperties(subscribeDto, subscribe);
            subscribe.setParentId(subscribeDto.getId());
            subscribe.setSubscribeNumber(RandomUtil.getOrderNumbers(this.baseMapper.selectLastID()));
            subscribe.setTotal(subscribeDto.getTotal());
            subscribe.setCreationTime(new Date());
            this.baseMapper.insert(subscribe);

            AuditList auditList = new AuditList();
            auditList.setParentId(subscribe.getId());
            auditList.setProcessType("planPurchase");
            auditList.setCreationTime(new Date());
            // 添加审核记录
            for (String str : subscribeDto.getApproval()) {
                auditList.setNameId(str);
                auditList.setTypes("1");
                auditListMapper.insert(auditList);
            }
            for (String str2 : subscribeDto.getNotify()) {
                auditList.setNameId(str2);
                auditList.setTypes("2");
                auditListMapper.insert(auditList);
            }
            if (subscribeDto.getCommodityList().size() > 0) {
                List<CommodityVo> commodityVoList = subscribeDto.getCommodityList();
                List<GoodsPoolCommodity> goodsPoolCommodityList = commodityVoList.stream().map(item -> {
                    GoodsPoolCommodity commodity = new GoodsPoolCommodity();
                    commodity.setCommodityAmount(new BigDecimal(item.getCommodityAmount()));
                    commodity.setCommodityPrice(item.getCommodityPrice());
                    commodity.setCommodityId(item.getCommodityId());
                    commodity.setGoodsPoolId(subscribe.getId());
                    historicalProcurement(item);
                    return commodity;
                }).collect(Collectors.toList());
                goodsPoolCommodityService.saveBatch(goodsPoolCommodityList);
            }
            return ResultVo.success("采购单已生成");
        }
    }

    /**
     * 保存计划申请历史数据
     *
     * @param vo
     */
    public void historicalProcurement(CommodityVo vo) {
        List<HistoricalProcurement> commodity_id =
                historicalProcurementService.list(new QueryWrapper<HistoricalProcurement>()
                        .eq("commodity_id", vo.getCommodityId()));
        HistoricalProcurement procurement = new HistoricalProcurement();
        procurement.setCommodityId(vo.getCommodityId());
        procurement.setCommodityAmount(vo.getCommodityAmount());
        procurement.setCommodityPrice(vo.getCommodityPrice());
        procurement.setSupplierId(vo.getSupplierId());
        procurement.setCreatorBy("admin");
        procurement.setCreationTime(new Date());
        if (commodity_id.size() > 0) {
            historicalProcurementService.updateById(procurement);
        } else {
            historicalProcurementService.save(procurement);
        }
    }

    /**
     * 钉钉申请通过生成采购单
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public ResultVo generatePurchaseOrder(Integer id, Integer status) {
        //判断id 是为空 id  85
        if (id == null || id.equals("")) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else if (status == null || status.equals("")) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else {
            // 修改申请列的专题
            // 根即可id 查询 申请是否存在 38
            List<Subscribe> subscribeList = baseMapper.selectList(new QueryWrapper<Subscribe>().eq("id", id));
            if (subscribeList.size() == 0) {
                throw new AntException(ResultCode.NOT_FOUND);
            }
            if (status == 2) {
                //判断是否已经申请采购单
                List<PurchaseOrders> purchaseOrdersList = purchaseOrdersMapper.selectList(
                        new QueryWrapper<PurchaseOrders>().eq("parent_id", id));
                if (purchaseOrdersList.size() != 0) {
                    throw new AntException(201, "已经生成采购单");
                } else {
                    //添加
                    List<GoodsPoolCommodity> goodsPoolCommodityList =
                            goodsPoolCommodityService.list(new QueryWrapper<GoodsPoolCommodity>()
                                    .eq("goods_pool_id", id));

                    if (goodsPoolCommodityList.size() != 0) {
                        List<PurchaseOrders> purchaseOrders = goodsPoolCommodityList.stream().map(item -> {
                            PurchaseOrders orders = new PurchaseOrders();
                            BigDecimal goodsTotalPrice =new BigDecimal(item.getCommodityAmount().toString()).multiply(item.getCommodityPrice());

                            orders.setOrdersNumber(subscribeList.get(0).getSubscribeNumber());
                            orders.setParentId(subscribeList.get(0).getId());
                            orders.setPurchaserId(subscribeList.get(0).getProposerId());
                            orders.setGoodsPoolCommodityId(item.getId());
                            orders.setGoodsTotalPrice(goodsTotalPrice.setScale(2,BigDecimal.ROUND_HALF_UP));
                            orders.setModifierBy("admin");
                            orders.setCreationTime(new Date());
                            return orders;
                        }).collect(Collectors.toList());
                        purchaseOrdersService.saveBatch(purchaseOrders);

                        //修改申请列表的状态审核状态
                        Subscribe subscribe = new Subscribe();
                        subscribe.setId(id);
                        subscribe.setProcessState(status);//2 通过申请
                        subscribe.setStatus("1");// 采购中
                        this.baseMapper.updateById(subscribe);
                        return ResultVo.success("生成成功");
                    } else {
                        throw new AntException(ResultCode.NOT_FOUND);
                    }
                }
            }
            return ResultVo.success("生成成功");
        }
    }


    /**
     * 采购入库
     *
     * @param id
     * @return
     */
    @Override
    public ResultVo PurchaseWarehousing(Integer id) {
        if (id == null) {
            throw new AntException(ResultCode.PARAM_TYPE_BIND_ERROR);
        } else {
            purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                    .set("is_warehousing", 1).eq("parent_id", id));
            return ResultVo.success("入库成功");
        }
    }


    @Override
    public List<Subscribe> getList(Wrapper<Subscribe> queryWrapper) {
        return null;
    }

    /**
     * 单个物品完成采购
     *
     * @param purchasesDto
     * @return
     */
    @Override
    @Transactional
    public ResultVo goodSingleCompletion(PurchaserDto purchasesDto) {
        //46 修改申请单中每个物品的 状态以及 供应商 和对应 物品的价格
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        // 计算价格
        System.out.println(purchasesDto);
        BigDecimal goodsTotalPrice=new BigDecimal(purchasesDto.getCommodityAmount())
                .multiply(purchasesDto.getCommodityPrice());
        UpdateWrapper<PurchaseOrders> wrappers = new UpdateWrapper<>();
        wrappers.set("goods_status", purchasesDto.getGoodsStatus()); //0未完成 1保存中 2 已完成 3 入库
        wrappers.set("channel", purchasesDto.getChannel());
        wrappers.set("payment_method", purchasesDto.getPaymentMethod());
        wrappers.set("goods_total_price",goodsTotalPrice.setScale(2,BigDecimal.ROUND_HALF_UP));
        wrappers.set("remark", purchasesDto.getRemark());
        wrappers.eq("id", purchasesDto.getPurchaseOrdersId());
        purchaseOrdersService.update(wrappers);

        UpdateWrapper<GoodsPoolCommodity> wrapper = new UpdateWrapper<>();
        wrapper.set("commodity_amount", new BigDecimal(purchasesDto.getCommodityAmount()));
        wrapper.set("commodity_price", purchasesDto.getCommodityPrice());
        wrapper.set("channel", purchasesDto.getChannel());
        wrapper.eq("id", purchasesDto.getGoodsPoolCommodityId());
        goodsPoolCommodityService.update(wrapper);
        //TODO
        if(purchasesDto.getSupList().size()>0){
            purchasesDto.getSupList().stream().forEach(item->{
                SupplierPayList payList = new SupplierPayList();
                payList.setSupplierId(item.getSupplierId());
                payList.setSubscribeId(purchasesDto.getSubscribeId());
                payList.setPurchaseOrdersId(purchasesDto.getPurchaseOrdersId());
                payList.setPrice(purchasesDto.getCommodityPrice());
                payList.setAmount(purchasesDto.getCommodityAmount());
                payList.setGoodsPoolCommodityId(purchasesDto.getGoodsPoolCommodityId());
                payList.setTotalPrice(goodsTotalPrice);
                payList.setPurchaserId(purchasesDto.getPurchaserId());
                payList.setHandleId(userInfo.getNameId());
                payList.setCommodityId(purchasesDto.getCommodityId());
                payList.setCreationTime(new Date());
                supplierPayListService.save(payList);
            });
        }
        return ResultVo.success("完成采购");
    }

    /**
     * 采购单完成
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public ResultVo goodAllCompleted(Integer id, Integer uid) {
        if (id == null) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else {
            MergeProcurement procurement = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                    .like("subscribe_id", id).eq("purchaser_id", uid));
            if (procurement == null) {
                return ResultVo.success("订单不存在");
            }
            List<String> asList = Arrays.asList(procurement.getSubscribeId().split(","));

            List<Subscribe> subscribeList = subscribeService.list(new QueryWrapper<Subscribe>()
                    .in("id", asList));
            if (subscribeList != null && subscribeList.size() > 0) {
                subscribeList.stream().forEach(item -> {
                    List<PurchaseOrders> list = purchaseOrdersService.list(new QueryWrapper<PurchaseOrders>()
                            .in("parent_id", item.getId()).eq("purchaser_id", uid));
                    if (list != null) {
                        list.stream().map(p -> {
                            if (p.getGoodsStatus() == 0) {
                                throw new AntException("请完成采购单中的物品");
                            }
                            return item;
                        }).collect(Collectors.toList());
                        BigDecimal reduce =
                                list.stream().map(PurchaseOrders::getGoodsTotalPrice).reduce(BigDecimal.ZERO,
                                        BigDecimal::add);
                        subscribeService.update(new UpdateWrapper<Subscribe>()
                                .set("price", reduce).set("status", 3)
                                .in("id", item.getId()));
                        goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 4).eq("id",
                                item.getParentId()));
                    }
                });
                return ResultVo.success("完成采购");
            } else {
                return ResultVo.success("订单不存在");
            }
        }

    }

    @Override
    public ResultVo price() {
        Map<String, Object> map = new HashMap<>();
        map.put("price", this.baseMapper.price());
        map.put("consumePrice", this.baseMapper.consumePrice());
        return ResultVo.success("获取成功", map);
    }

    @Override
    public ResultVo updateImgUrl(ImgUrlDto dto) {
        if (dto.getOrderList().size() > 0) {
            List<Subscribe> subscribeList = dto.getOrderList().stream().map(item -> {
                Subscribe subscribe = new Subscribe();
                subscribe.setId(item.getId()); // 物品id 88 ，89，，89
                subscribe.setBills(dto.getImgId().toString());// 20
                return subscribe;
            }).collect(Collectors.toList());
            subscribeService.updateBatchById(subscribeList);
            //修改物品图片路径
            dto.getOrderList().stream().map(item -> {
                purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                        .set("img", dto.getImgId()).eq("parent_id", item.getId()));
                return item;
            }).collect(Collectors.toList());
            return ResultVo.success("更新成功");
        } else {
            throw new AntException(ResultCode.NOT_FOUND);
        }
    }

    @Override
    public ResultVo subscribeReimbursement(Integer[] ids, Integer purchaserId) {
        List<Subscribe> list = this.list(new QueryWrapper<Subscribe>().in("id", Arrays.asList(ids)));
        //  [138,139]
        List<Subscribe> subscribeList = list.stream().map(item -> {
            List<PurchaseVo> purchaseVoList = this.baseMapper.getPurchaseVoList(item.getId(), purchaserId);
            item.setPurchaseVoList(purchaseVoList);
            return item;
        }).collect(Collectors.toList());

        return ResultVo.success("查询成功", subscribeList);
    }

    /**
     * 小程序采购单完成采购
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public ResultVo subscribeAllCompleted(List<SubDto> dto) {
        if (dto.size() == 0) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else {
            dto.stream().forEach(item -> {
                item.getCommodityVos().stream().forEach(items -> {
                    PurchaseOrders orders = new PurchaseOrders();
                    GoodsPoolCommodity goodsPoolCommodity = new GoodsPoolCommodity();
                    BigDecimal amount = new BigDecimal(items.getCommodityAmount());
                    BigDecimal TotalPrice = amount.multiply(items.getCommodityPrice());
                    orders.setGoodsTotalPrice(TotalPrice);
                    orders.setId(items.getPurchaseOrdersId());
                    orders.setGoodsStatus(2);
                    orders.setPurchaserId(items.getPurchaserId());
                    purchaseOrdersService.updateById(orders);
                    //修改申请中间表的实际参数
                    goodsPoolCommodity.setCommodityAmount( new BigDecimal(items.getCommodityAmount()));
                    goodsPoolCommodity.setCommodityPrice(items.getCommodityPrice());
                    goodsPoolCommodity.setId(items.getGoodsPoolCommodityId());
                    goodsPoolCommodityService.updateById(goodsPoolCommodity);
                });
                // 是否全部采购完成
                List<PurchaseOrders> ordersList = purchaseOrdersService.list(new QueryWrapper<PurchaseOrders>().eq(
                        "goods_status", 1).eq(
                        "parent_id", item.getSubscribeId()));
                if (ordersList.size() == 0) {
                    //取值
                    List<PurchaseOrders> list = purchaseOrdersService.list(new QueryWrapper<PurchaseOrders>().eq(
                            "goods_status", 2).eq(
                            "parent_id", item.getSubscribeId()));
                    BigDecimal totalPrice =
                            list.stream().map(PurchaseOrders::getGoodsTotalPrice).reduce(BigDecimal.ZERO,
                                    BigDecimal::add);

                    subscribeService.update(new UpdateWrapper<Subscribe>()
                            .set("price", totalPrice).set("status", 3)
                            .set("remark", item.getRemarks())
                            .eq("id", item.getSubscribeId()));
                    Subscribe serviceOne = subscribeService.getOne(new QueryWrapper<Subscribe>().eq("id",
                            item.getSubscribeId()));
                    if (serviceOne != null) {
                        goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 4)
                                .eq("id", serviceOne.getParentId()));
                    }

                }
            });
            return ResultVo.success("完成采购");
        }
    }

    @Override
    public boolean save(Subscribe entity) {
        return super.save(entity);
    }

    /**
     * 小程序获取采购单
     *
     * @param dto
     * @return
     */
    @Override
    public PageInfo<Subscribe> appletQueryAllPage(SubscribeDto dto) {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            PageHelper.startPage(dto.getPageIndex(), dto.getPageSize());
            QueryWrapper<Subscribe> wrapper = new QueryWrapper<>();
            // 编号
            if (StringUtils.isNotEmpty(dto.getSubscribeNumber())) {
                wrapper.lambda().like(Subscribe::getSubscribeNumber, dto.getSubscribeNumber());
            }
            //支付方式方式
            if (StringUtils.isNotEmpty(dto.getPayType())) {
                wrapper.lambda().eq(Subscribe::getPayType, dto.getPayType());
            }
            //部门id
            if (dto.getDepartmentId() != null) {
                wrapper.lambda().eq(Subscribe::getDepartmentId, dto.getDepartmentId());
            }
            // 采购状态
            if (StringUtils.isNotEmpty(dto.getStatus())) {
                wrapper.in("status", Arrays.asList(dto.getStatus().split(",")));
            }
            // 采购状态
            if (StringUtils.isNotEmpty(dto.getPurchaseType())) {
                wrapper.lambda().eq(Subscribe::getPurchaseType, dto.getPurchaseType());
            }
            // 是否报销
            if (dto.getReimbursement() != null) {
                wrapper.lambda().eq(Subscribe::getReimbursement, dto.getReimbursement());
            }
            if (userInfo!=null && userInfo.getRoles() == null) {
                wrapper.lambda().in(Subscribe::getPurchaserId, userInfo.getNameId());
            }
//            if (userInfo!=null && userInfo.getRoles() == null) {
//                wrapper.lambda().and(qr->qr.eq(Subscribe::getCreatorBy, userInfo.getNameId()).or()
//                        .eq(Subscribe::getPurchaserId, userInfo.getNameId()));
//            }else{
//                //采购人id
//                if (StringUtils.isNotEmpty(dto.getPurchaserId())) {
//                    // wrapper.lambda().in(Subscribe::getPurchaserId,dto.getPurchaserId());
//                    wrapper.like("purchaser_id", dto.getPurchaserId());
//                }
//            }
            if (userInfo.getRoles() != null && userInfo.getRoles().equals("admin")) {
                wrapper.lambda().eq(Subscribe::getCityId, userInfo.getCityId());
            }
            wrapper.orderByDesc("id");
            List<Subscribe> subscribeList = this.baseMapper.selectList(wrapper);
            subscribeList.stream().map(item -> {
                List<CommodityVo> purchaseOrdersList =
                        purchaseOrdersMapper.selectCommodityVo(Integer.valueOf(dto.getPurchaserId()), item.getId());
                item.setCommodityVoList(purchaseOrdersList);
                MergeProcurement one = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>().select("subscribe_id")
                        .like("subscribe_id", item.getId()).eq("purchaser_id", dto.getPurchaserId()));
                if (one != null) {
                    item.setMergeId(1);
                    item.setMergeIds(one.getSubscribeId());
                } else {
                    item.setMergeIds(item.getId().toString());
                }

                MergeSubscribe list = mergeSubscribeService.getOne(new QueryWrapper<MergeSubscribe>().select("subscribe_id")
                        .like("subscribe_id", item.getId()).eq("purchaser_id", dto.getPurchaserId()));
                // 查看合并的 采购单号
                // MergeProcurement list = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                //    .like("subscribe_id", item.getId()).eq("purchaser_id", dto.getPurchaserId()));
                if (list != null) {
                    item.setStatus(list.getStatus() == 1 ? "3" : item.getStatus());
                    item.setPayStatus(list.getStatus() == 1 ? 2 : item.getPayStatus());
                }
                return item;
            }).collect(Collectors.toList());
            PageInfo<Subscribe> pageInfo = new PageInfo<>(subscribeList);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }


    @Override
    @Transactional
    public List<Subscribe> getAppletPurchaseOrderByIds(String ids, Integer pid) {

        if (ids == null) {
            throw new AntException("id不能为空");
        }
        MergeProcurement procurement;
        if (pid == 0) {
            procurement = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                    .like("subscribe_id", ids));
        } else {
            procurement = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                    .like("subscribe_id", ids).eq("purchaser_id", pid));
        }

        List<Subscribe> list;
        List<String> asList;
        if (procurement != null && pid != 0) {
            asList = Arrays.asList(procurement.getSubscribeId().split(","));
            list = this.list(new QueryWrapper<Subscribe>().in("id", asList));
        } else {
            asList = Arrays.asList(ids.split(","));
            list = this.list(new QueryWrapper<Subscribe>().in("id", asList));

        }
        list.forEach(item -> {
            List<CommodityVo> purchaseOrdersList = null;
            if (pid == 0) {
                purchaseOrdersList = purchaseOrdersMapper.selectCommodityVos(item.getId(), null);
            } else {
                purchaseOrdersList = purchaseOrdersMapper.selectCommodityVos(item.getId(),
                        procurement == null ? pid : procurement.getPurchaserId());
            }
            purchaseOrdersList.stream().forEach(m -> {
                List<SupplierListDto> dtoList = new ArrayList<>();
                supplierPayListService.list(new QueryWrapper<SupplierPayList>()
                        .eq("purchase_orders_id", m.getPurchaseOrdersId())
                        .eq("subscribe_id", m.getSubscribeId())).stream().map(item1 -> {
                    SupplierListDto dto = new SupplierListDto();
                    dto.setSupplierId(item1.getSupplierId());
                    dto.setAmount(item1.getAmount());
                    dtoList.add(dto);
                    return null;
                }).collect(Collectors.toList());
                m.setSupList(dtoList);
            });
            item.setCommodityVoList(purchaseOrdersList);

        });
        return list;
    }

    @Override
    @Transactional
    public Subscribe getAppletPurchaseOrderById(Integer id) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        if (id == null) {
            throw new AntException("id不能为空");
        }
        Subscribe list = this.baseMapper.selectOne(new QueryWrapper<Subscribe>().eq("id",id));
        if(list!=null){
            List<CommodityVo> purchaseOrdersList = purchaseOrdersMapper.selectCommodityVos(list.getId(), userInfo.getNameId());
            purchaseOrdersList.stream().forEach(m -> {
                List<SupplierListDto> dtoList = new ArrayList<>();
                supplierPayListService.list(new QueryWrapper<SupplierPayList>()
                        .eq("purchase_orders_id", m.getPurchaseOrdersId())
                        .eq("subscribe_id", m.getSubscribeId())).stream().map(item1 -> {
                    SupplierListDto dto = new SupplierListDto();
                    dto.setSupplierId(item1.getSupplierId());
                    dto.setAmount(item1.getAmount());
                    dtoList.add(dto);
                    return null;
                }).collect(Collectors.toList());
                m.setSupList(dtoList);
            });list.setCommodityVoList(purchaseOrdersList);
            return list;
        }else{
            throw new AntException("id不能为空");
        }
    }


    /**
     * 小程序采购单处理
     *
     * @param mergeDto
     * @return
     */
    @Override
    @Transactional
    public ResultVo getMergeApply(MergeDto mergeDto) {
        if (mergeDto.getId().size() > 0) {
            List<Subscribe> list = this.list(new QueryWrapper<Subscribe>().in("id",  mergeDto.getId()));
            List<MergeProcurement> procurementList =
                    mergeProcurementService.list(new QueryWrapper<MergeProcurement>().in(
                            "subscribe_id", mergeDto.getId())
                            .eq("purchaser_id", mergeDto.getPurchaserId()));
            MergeProcurement procurement = new MergeProcurement();
            if (procurementList.size() == 0) {
                list.stream().forEach(item->{
                    procurement.setSubscribeId(item.getId().toString());
                    procurement.setSubscribeNumber("HB" + RandomUtil.getOrderNumbers(procurementMapper.selectMaxId()));
                    procurement.setPurchaserId(mergeDto.getPurchaserId());
                    procurement.setApplyPrice(mergeDto.getPrice());
                    procurement.setCreationTime(new Date());
                    mergeProcurementService.save(procurement);
                });

                if (mergeDto.getPaymentMethod() == 38) {
                    // 判断是否为空
                    if (mergeDto.getIsApproved() == 1) {
                        if (mergeDto.getApproval().size() == 0 || mergeDto.getApproval() == null) {
                            throw new AntException("请选择审批人员");
                        }
                        AuditList auditList = new AuditList();
                        auditList.setParentId(procurement.getId());
                        auditList.setProcessType("payment");
                        auditList.setCreationTime(new Date());
                        // 添加审核记录
                        for (String str : mergeDto.getApproval()) {
                            auditList.setNameId(str);
                            auditList.setTypes("1");
                            auditListService.save(auditList);
                        }
                        if (mergeDto.getNotify().size() == 0 || mergeDto.getNotify() == null) {
                            throw new AntException("请选择抄送人");
                        }
                        for (String str2 : mergeDto.getNotify()) {
                            auditList.setNameId(str2);
                            auditList.setTypes("2");
                            auditListService.save(auditList);
                        }
                        // 发起钉钉审批
                        // 通过 getUserId()
                        Payment payment = new Payment();
                        payment.setUserId(mergeDto.getUserId());
                        try {
                            Long personneDeplList = DingDingUtil.getPersonneDepld(mergeDto.getUserId(),
                                    DingDingUtil.obtainToken());
                            Integer depid = personneDeplList.intValue();
                            payment.setDeptId(depid);
                        } catch (ApiException e) {
                            e.printStackTrace();
                        }
                        payment.setApproval(mergeDto.getApproval());
                        payment.setNotify(mergeDto.getNotify());
                        payment.setMoney(mergeDto.getPrice());
                        payment.setPayType(mergeDto.getPayType());
                        payment.setReason(mergeDto.getRemarks());
                        payment.setCity(mergeDto.getCityName());
                        payment.setDepartment(mergeDto.getDepartmentName());
                        payment.setCompanyName(mergeDto.getCompanyName());
                        payment.setDate(mergeDto.getDate());
                        payment.setAccountNumber(mergeDto.getAccountNumber());
                        payment.setUrgency(mergeDto.getUrgency());
                        payment.setOpeningBank(mergeDto.getOpeningBank());
                        payment.setPayee(mergeDto.getPayee());
                        //采购申请钉钉审批
                        try {
                            System.out.println("dto:" + payment);
                            String process_instance_ids = addDingDing(payment);
                            // 修改审批id
                            UpdateWrapper<MergeProcurement> updateWrapper = new UpdateWrapper<MergeProcurement>().set(
                                    "process_instance_id", process_instance_ids).eq("id", procurement.getId());
                            mergeProcurementService.update(updateWrapper);
                            Subscribe subscribe = new Subscribe();
                            list.stream().map(item -> {
                                subscribe.setId(item.getId());
                                subscribe.setTotalPrice(mergeDto.getPrice());
                                subscribe.setIsMerge(1);
                                subscribe.setPayStatus(1);
                                subscribe.setPayType(mergeDto.getPaymentMethod().toString());
                                subscribeService.updateById(subscribe);
                                purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                                        .set("payment_method", mergeDto.getPaymentMethod())
                                        .eq("parent_id", item.getId()));
                                return subscribe;
                            }).collect(Collectors.toList());
                            return ResultVo.success("处理成功");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    return ResultVo.fail("处理成功");
                } else {
                    list.stream().map(item -> {
                        Subscribe subscribe = new Subscribe();
                        subscribe.setId(item.getId());
                        subscribe.setStatus("1");
                        subscribe.setTotalPrice(mergeDto.getPrice());
                        subscribe.setIsMerge(1);
                        subscribe.setPayType(mergeDto.getPaymentMethod().toString());
                        subscribe.setPayStatus(2);
                        subscribeService.updateById(subscribe);
                        purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                                .set("payment_method", mergeDto.getPaymentMethod())
                                .set("channel", mergeDto.getPaymentMethod() == 16 ? 41 : null)
                                .eq("parent_id", item.getId()));
                        goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 3).eq("id",
                                item.getParentId()));
                        return subscribe;
                    }).collect(Collectors.toList());
                    return ResultVo.success("处理成功");
                }

            } else {
                return ResultVo.fail("采购单已处理");
            }
        } else {
            // 是否要发起请款审批
            return ResultVo.fail("数据不能为空");
        }
    }

    public String addDingDing(Payment payment) throws Exception {
        FundsDto fundsDto = new FundsDto();
        fundsDto.setAccess_token(DingDingUtil.obtainToken());
        fundsDto.setOriginator_userid(payment.getUserId());
        fundsDto.setDeptId(payment.getDeptId());
        fundsDto.setApprover_userid(payment.getApproval());
        fundsDto.setCc_userId(payment.getNotify());
        fundsDto.setCity(payment.getCity());// TODO
        fundsDto.setDepartment(payment.getDepartment());// TODO: 2020/3/26  部门
        fundsDto.setDate(payment.getDate());
        fundsDto.setCompanyName(payment.getCompanyName());
        fundsDto.setUrgency(payment.getUrgency());
        fundsDto.setReason(payment.getReason());
        fundsDto.setAmount(payment.getMoney().toString());
        fundsDto.setUnit(payment.getPayee());
        fundsDto.setBankName(payment.getOpeningBank());
        fundsDto.setBankAccount(payment.getAccountNumber());
        fundsDto.setPayType(payment.getPayType());
        String process_instance_id = DingDingUtil.OldPurchaseRequest(fundsDto);
        return process_instance_id;
    }

    /**
     * @param id
     * @return
     */
    @Override
    public List<PurchaserRecord> findSubscribeIdPurchaserRecord(Integer id) {
        List<PurchaserSubscribe> purchaserSubscribeList =
                purchaserSubscribeService.list(new QueryWrapper<PurchaserSubscribe>().eq("subscribe_id", id));
        if(purchaserSubscribeList!=null && purchaserSubscribeList.size()>0){
            List<Integer> list =
                    purchaserSubscribeList.stream().map(PurchaserSubscribe::getPurchaserRecordId).collect(Collectors.toList());
            List<PurchaserRecord> recordList = purchaserRecordService.list(new QueryWrapper<PurchaserRecord>().in("id", list));
            recordList.stream().map(record -> {
                List<PurchaseDetailsVo> purchaseVoList = purchaserRecordMapper.getPurchaseRecordByIdes(record.getId());
                if (purchaseVoList.size() > 0) {
                    //获取票据
                    if (purchaseVoList.get(0).getBills() != null && !purchaseVoList.get(0).getBills().equals("")) {
                        List<Integer> idList = Arrays.stream(purchaseVoList.get(0).getBills().split(","))
                                .map(Integer::parseInt).collect(Collectors.toList());
                        List<PurchaserRecordImg> recordImgs =
                                recordImgService.list(new QueryWrapper<PurchaserRecordImg>().in("id", idList));
                        String collect =
                                recordImgs.stream().map(recordImg -> recordImg.getUrl()).collect(Collectors.joining(","));
                        purchaseVoList.stream().map(item -> {
                            item.setUrl(collect);
                            return item;
                        }).collect(Collectors.toList());
                        record.setImgUrlId(collect);
                    }
                    record.setPurchaseDetailsVo(purchaseVoList);
                }
                return record;
            }).collect(Collectors.toList());
            return recordList;
        }

            return null;


    }

    @Override
    public AuditList selectIsAudit(String processInstanceId, String user_id) {
        MergeProcurement subscribe = mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>()
                .eq("process_instance_id", processInstanceId));
        if (subscribe != null) {
            AuditList parentId = auditListService.getOne(new QueryWrapper<AuditList>()
                    .eq("parent_id", subscribe.getId())
                    .eq("process_type", "payment")
                    .eq("types", "1")
                    .eq("name_id", user_id));
            if (parentId != null) {
                return parentId;
            }
            return null;
        }
        return null;
    }

    /**
     * 钉钉回调结果
     *
     * @param processInstanceId
     * @param opinion
     */
    @Override
    public void getprocessInstanceIdById(String processInstanceId, String opinion) {
        MergeProcurement procurement =
                mergeProcurementService.getOne(new QueryWrapper<MergeProcurement>().eq("process_instance_id",
                        processInstanceId));
        if (procurement != null) {
            List<String> list = Arrays.stream(procurement.getSubscribeId().split(",")).collect(Collectors.toList());
            list.stream().forEach(item -> {
                Subscribe subscribe = new Subscribe();
                subscribe.setId(Integer.valueOf(item));
                subscribe.setPayStatus(opinion.equals("agree") ? 2 : 3);
                subscribe.setStatus("1");
                subscribeService.updateById(subscribe);
                Subscribe id = subscribeService.getOne(new QueryWrapper<Subscribe>().eq("id", item));
                goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 3).eq("id",
                        id.getParentId()));
            });
        }
    }

    @Override
    public Map<String,Object> queryWarehousingAllPage(SubscribeDto dto) {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            ArrayList<Integer> cid = new ArrayList<>();
            if(userInfo.getRoles()==null){
                cid.add(userInfo.getCityId());
                dto.setCityId(cid);
                dto.setPurchaserId(userInfo.getNameId().toString());
            }
            if(userInfo.getRoles()!=null &&  userInfo.getRoles().equals("admin")){
                cid.add(userInfo.getCityId());
                dto.setCityId(cid);
            }
            if(StringUtils.isEmpty(dto.getStatus())){
                dto.setStatus("3");
            }
            if(dto.getTimes()!=null && dto.getTimes().size()>0){
                String stats=dto.getTimes().get(0)+" 00:00:00";
                String end=dto.getTimes().get(1)+" 23:59:59";
                ArrayList<String> time = new ArrayList<>();
                time.add(stats);
                time.add(end);
                dto.setTimes(time);
            }

            List<Integer> ids = this.baseMapper.selectListByIds(dto);
            List<Subscribe> subscribeList=new ArrayList<>();
            if(ids.size()>0){
                subscribeList = this.baseMapper.selectList(
                        new QueryWrapper<Subscribe>().in("id", ids).orderByDesc("id")
                );
                subscribeList.forEach(item -> {
                    item.setDepartment(departmentService.getDepName(item.getDepartmentId()));
                    List<CommodityVo> commodityVo = commodityMapper.commodityAndGoodLists(item.getId());
                    item.setCommodityVoList(commodityVo);
                });
            }
            Map<String,Object> map=new HashMap<>();
            map.put("list",subscribeList);
            map.put("total",this.baseMapper.selectListByIdsCount(dto));
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    @Override
    public Map<String,Object> queryCarAllPage(SubscribeDto dto) {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            ArrayList<Integer> cid = new ArrayList<>();
            if(userInfo.getRoles()==null){
                cid.add(userInfo.getCityId());
                dto.setCityId(cid);
                //dto.setPurchaserId(userInfo.getNameId().toString());
            }
            if(userInfo.getRoles()!=null && userInfo.getRoles().equals("admin")){
                cid.add(userInfo.getCityId());
                dto.setCityId(cid);
            }
            if(StringUtils.isEmpty(dto.getStatus())){
                dto.setStatus("0");
            }
            if(dto.getTimes()!=null && dto.getTimes().size()>0){
                String stats=dto.getTimes().get(0)+" 00:00:00";
                String end=dto.getTimes().get(1)+" 23:59:59";
                ArrayList<String> time = new ArrayList<>();
                time.add(stats);
                time.add(end);
                dto.setTimes(time);
            }

            List<Integer> ids = this.baseMapper.selectListCarByIds(dto);
            List<Subscribe> subscribeList=new ArrayList<>();
            if(ids.size()>0){
                subscribeList = this.baseMapper.selectList(
                        new QueryWrapper<Subscribe>().in("id", ids).orderByDesc("id")
                );
                subscribeList.forEach(item -> {
                    item.setDepartment(departmentService.getDepName(item.getDepartmentId()));
                    List<CommodityVo> commodityVo = commodityMapper.commodityAndGoodLists(item.getId());
                    item.setCommodityVoList(commodityVo);
                });
            }
            Map<String,Object> map=new HashMap<>();
            map.put("list",subscribeList);
            map.put("total",this.baseMapper.selectListByIdsCarCount(dto));
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    @Override
    public void getCarAdoptApply(Integer id) {
        Subscribe subscribe = this.baseMapper.selectOne(new QueryWrapper<Subscribe>().eq("id", id));
        if (subscribe != null) {
            Subscribe sub=new Subscribe();
            sub.setStatus("3");
            sub.setId(id);
            this.baseMapper.updateById(sub);
            purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                    .set("goods_status",2).eq("parent_id",id));
        }
    }
}
